<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head>
	<meta http-equiv="content-type" content="text/html; charset=UTF-8">
	<meta http-equiv="Content-Language" content="en-us">
	<script type="text/javascript" src="Alan%20Storm%20%20Sugar%20CRM%20Hello%20World%20for%20PHP%20Developers_files/jquery_002.js"></script>
	<script type="text/javascript" src="Alan%20Storm%20%20Sugar%20CRM%20Hello%20World%20for%20PHP%20Developers_files/jquery.js"></script>	
	<link rel="alternate" type="application/atom+xml" title="Recent Entries" href="http://alanstorm.com/atom">	
	<link rel="stylesheet" type="text/css" href="Alan%20Storm%20%20Sugar%20CRM%20Hello%20World%20for%20PHP%20Developers_files/a.css">
	<!--[if IE]><link rel="stylesheet" type="text/css" href="/2009/css/ie.css" /><![endif]-->
	
	<link rel="stylesheet" type="text/css" href="Alan%20Storm%20%20Sugar%20CRM%20Hello%20World%20for%20PHP%20Developers_files/jquery.css">	
	
	<link href="Alan%20Storm%20%20Sugar%20CRM%20Hello%20World%20for%20PHP%20Developers_files/prettify.css" type="text/css" rel="stylesheet">
	<script type="text/javascript" src="Alan%20Storm%20%20Sugar%20CRM%20Hello%20World%20for%20PHP%20Developers_files/prettify.js"></script>
	<script type="text/javascript" src="Alan%20Storm%20%20Sugar%20CRM%20Hello%20World%20for%20PHP%20Developers_files/shCore.js"></script> 
	<script type="text/javascript" src="Alan%20Storm%20%20Sugar%20CRM%20Hello%20World%20for%20PHP%20Developers_files/shBrushJScript.js"></script> 
	<script type="text/javascript" src="Alan%20Storm%20%20Sugar%20CRM%20Hello%20World%20for%20PHP%20Developers_files/shBrushPhp.js"></script> 	
	<script type="text/javascript" src="Alan%20Storm%20%20Sugar%20CRM%20Hello%20World%20for%20PHP%20Developers_files/shBrushXml.js"></script> 	
	<script type="text/javascript" src="Alan%20Storm%20%20Sugar%20CRM%20Hello%20World%20for%20PHP%20Developers_files/shBrushPython.js"></script>
	<script type="text/javascript" src="Alan%20Storm%20%20Sugar%20CRM%20Hello%20World%20for%20PHP%20Developers_files/shBrushYaml.js"></script>	
	

	<link type="text/css" rel="stylesheet" href="Alan%20Storm%20%20Sugar%20CRM%20Hello%20World%20for%20PHP%20Developers_files/shCoreDefault.css"> 
	<script type="text/javascript">SyntaxHighlighter.all();</script> 

	
	<title>Alan Storm: Sugar CRM Hello World for PHP Developers </title>	
<script src="Alan%20Storm%20%20Sugar%20CRM%20Hello%20World%20for%20PHP%20Developers_files/embed.js" async="" type="text/javascript"></script></head>
<body>
<div id="wrap">
	
<div id="header">
	<img src="Alan%20Storm%20%20Sugar%20CRM%20Hello%20World%20for%20PHP%20Developers_files/title-w-header.gif" style="position:relative;top:6px;left:10px;">
</div>

<div id="content-wrap">
	<div id="sidebar">	
		        <img src="Alan%20Storm%20%20Sugar%20CRM%20Hello%20World%20for%20PHP%20Developers_files/valve.jpg" alt="Say Yes" id="sidebar-img" border="0" height="90" width="200">
		<ul id="nav" class="nostyle">
<li class="first"><a style="font-size: 12px;" href="http://alanstorm.com/">Home</a></li> 
<li><a style="font-size: 12px;" href="http://alanstorm.com/archives">Archive</a></li> 
<li><a style="font-size: 12px;" href="http://alanstorm.com/projects">Projects</a></li> 
<li class="last"><a style="font-size: 12px;" href="http://alanstorm.com/contact">Contact</a></li>
</ul>
<h2 class="categories" style="margin-top:20px;">Article Categories</h2>
<ul id="ascategories">
	<li><a rel="category tag" href="http://alanstorm.com/category/magento">Magento</a></li>
	<li><a rel="category tag" href="http://alanstorm.com/category/orocrm">OroCRM</a></li>
	<li><a rel="category tag" href="http://alanstorm.com/category/modern_php">Modern PHP</a></li>
	<li><a rel="category tag" href="http://alanstorm.com/category/sugarcrm">SugarCRM</a></li>
	<li><a rel="category tag" href="http://alanstorm.com/category/drupal">Drupal</a></li>
	<li><a rel="category tag" href="http://alanstorm.com/category/webos">WebOS (HP/Palm)</a></li>	
	<li><a rel="category tag" href="http://alanstorm.com/category/python">Python</a></li>
	<li><a rel="category tag" href="http://alanstorm.com/category/applescript">AppleScript</a></li>
	<li><a href="http://alanstorm.com/links">Links</a> (beta)</li>
</ul>
<h2 class="categories" style="margin-top:20px;">Quickies Sites</h2>
<ul id="quickies">
    <li><a href="http://magento-quickies.alanstorm.com/">Magento Quickies</a></li>
    <li><a href="http://oro-quickies.alanstorm.com/">OroCRM Quickies</a></li>
    <li><a href="http://wordpress-quickies.alanstorm.com/">Wordpress Quickies</a></li>
</ul>
<a href="http://store.alanstorm.com/products/no-frills-magento-layout"><img src="Alan%20Storm%20%20Sugar%20CRM%20Hello%20World%20for%20PHP%20Developers_files/no_frills_200x.png" style="display:block;margin-bottom:1em" border="0" height="275" width="200"></a>

<p>
No Frills Magento Layout is the only Magento layout book you'll ever need. 
<a href="http://store.alanstorm.com/products/no-frills-magento-layout">Get your copy today</a>!
</p>


<h2 class="categories" style="margin-top:20px;">Quickies</h2>
<p>
Development oriented blogs with less detailed, but still vital, programming tips.
</p>
<ul id="ascategories">
	<li><a href="http://magento-quickies.tumblr.com/">Magento Quickies</a></li>
	<li><a href="http://wordpressquickies.tumblr.com/">Wordpress Quickies</a></li>
	<li><a href="http://oroquickies.wordpress.com/">Oro Quickies</a></li>
</ul>

<p>Alan Storm is a human being living in Portland, OR by way of Seattle,
 WA by way of Portland, OR by way of Rochester, NY.  He likes making 
computers do things, and talks about that here.  </p>

<p id="not-resume">
He also likes to make things on the web. If you need something 
made on the web, <a href="http://alanstorm.com/site/contact">drop him a line</a>.
</p>

<p>We're a little worried about his penchant for slipping into the third person narrative form.</p>

<h2 class="rss"><a href="http://alanstorm.com/atom">Follow the Feed</a></h2>

<h2 class="twitter"><a href="http://twitter.com/alanstorm">Follow the Twitter</a></h2>
	</div>
	<div id="content">	
		<h1><a href="http://alanstorm.com/sugar_crm_hello_world">Sugar CRM Hello World for PHP Developers</a></h1>

<p style="border: 1px dashed rgb(0, 0, 0); padding: 5px 10px; background-color: rgb(255, 255, 255);cursor:pointer" onclick="document.location='http://store.alanstorm.com/products/commerce-bug-2'"><img src="Alan%20Storm%20%20Sugar%20CRM%20Hello%20World%20for%20PHP%20Developers_files/cb-icon.png" style="margin-right:10px" align="left" height="75" width="75">
    Like this article?  Frustrated by Magento? Then you’ll love <a href="http://store.alanstorm.com/products/commerce-bug-2">Commerce Bug</a>,
 the must have debugging extension for anyone using Magento. Whether 
you’re just starting out or you’re a seasoned pro, Commerce Bug will 
save you and your team hours everyday. <a href="http://store.alanstorm.com/products/commerce-bug-2">Grab a copy</a> and start working <strong>with</strong> Magento instead of against it.
</p>

<p><em>This article is part of a <a href="http://alanstorm.com/category/sugarcrm#sugarcrm_for_php_developers">longer series</a>
 
exploring SugarCRM's features from a PHP developer's point of view. 
While this article contains useful stand-alone information, you'll want 
to read the <a href="http://alanstorm.com/category/sugarcrm#sugarcrm_for_php_developers">entire series</a> to fully understand what's going on</em>.

</p>

<p>Business programming frameworks are, as a rule, awful.  Whether you 
call it “agile”, “scrum”, or “my chaotic job where no one seems to be in
 charge until a crisis hits and there’s always a new crisis”, the story 
of business software development over the past 10  years has been doing 
more with less, attacking the immediate problems now, and letting the 
long term problems sort themselves out via human intervention 
—&nbsp;even if that intervention needs to happen at 1:45 AM on a 
Saturday. </p>

<p>While this has been a smart move for quarter-to-quarter business 
metrics, it leads to chaotic system code, which is maddening for a 
professional programmer who needs to work with these sorts of systems.  
By “professional programmer” I mean me, and by “these sorts of systems”,
 I specifically mean SugarCRM.</p>

<p>SugarCRM is a “Customer Relationship Management” system built with 
PHP. If Magento is a system where the developers took their abstractions
 a little overboard, then SugarCRM is the system where business took 
“ignore the developer’s concerns” a little overboard.  The result is a 
chaotic code-base with competing engineering visions that’s difficult 
for a newcomer to jump into. </p>

<p>Despite that, under the cruft and chaos, there <strong>is</strong> an
 MVC system in play, and understanding that system is your first step 
towards mastering SugarCRM programming.  With business relying more and 
more on the sort of business intelligence you can extract from a CRM, 
SugarCRM seems like a good tool to have in your belt.</p>

<p>Over the next few months I’m going to be exploring SugarCRM’s core 
code from the point of view of a PHP MVC developer.  These tutorials 
won’t be for everyone, but if you’re the sort of developer who needs to 
understand where all the pipes are going, then this series is for you. </p>

<p><em>The code samples in this article were tested against SugarCRM CE 
6.5.10, but the concepts should apply to future and past versions of the
 platform.</em></p>

<h2>Development Environment Pre-Flight</h2>

<p>Before we get started, a quick note about your development environment.</p>

<p>SugarCRM was originally written in a PHP 4 world, and much of the 
code still uses PHP 4 idioms.  Running SugarCRM with a modern version of
 PHP will result in a number of warnings being generated in your error 
logs, as well as in the browser if <code>display_errors</code> is set to true.</p>

<p><img src="Alan%20Storm%20%20Sugar%20CRM%20Hello%20World%20for%20PHP%20Developers_files/display_errors.png" border="0" height="516" width="713"></p>

<p>This is a perfect example of how a good business decision results in 
questionable engineering.  Rather than refactor this code to use modern 
standards, the SugarCRM team handles the problem by <a href="http://support.sugarcrm.com/05_Resources/03_Supported_Platforms/Sugar_6.5.x_Supported_Platforms">setting strict system requirements</a> and recommending users <a href="http://support.sugarcrm.com/04_Find_Answers/02KB/02Administration/100Troubleshooting/About_PHP_Notices,_Warnings,_and_Errors">set <code>display_errors</code> to Off</a>.  </p>

<p>I know this is a bad idea,&nbsp;you know it’s a bad idea, but in 
certain business cultures it’s a hard sell to take on a refactoring 
project when there’s no direct line to a revenue stream.</p>

<p>For now I’m leaving my PHP error reporting cranked as high as it goes and keeping <code>display_errors</code>
 off.  The ambitious among you might try creating a custom PHP error 
handler to filter these out, but that’s another topic for another day. </p>

<p>Also, the following code example were testing against <em>SugarCRM CE 6.5.10</em>, but the concepts should apply to all recent versions of the platform.</p>

<h2>SugarCRM Modules</h2>

<p>Step one to understanding Sugar CRM is to understand its module 
system.  Module, of course, is software development’s second favorite 
overloaded word (right after “Object Oriented”).  A SugarCRM module is 
not a <a href="http://en.wikipedia.org/wiki/Bertrand_Meyer">Bertrand Meyer</a> “lets have all the code play nice together” sort of thing.  Instead, it’s the tight coupling of </p>

<ul>
<li><p>A UI menu link to a page</p></li>
<li><p>A CRUD model for saving data</p></li>
<li><p>Auto generated UI for managing that data</p></li>
</ul>

<p>The SugarCRM development culture seems to shy away from understanding
 how the three items are implemented — the system ships with a module 
builder application that auto generates the PHP code a developer needs, 
and the core system code is built around supporting the module builder. 
 </p>

<p>We’re going to be taking the slow boat on this one. After enough 
articles we’ll eventually reach SugarCRM’s idea of a “module”, but for 
now think of SugarCRM as you would any other PHP MVC system. </p>

<h2>SugarCRM Routing</h2>

<p>The first shock an MVC developer faces when working with SugarCRM is there’s no URL based routing. SugarCRM requests <strong>do</strong> all go through a single <code>index.php</code> file, but it is query string parameters that drive which controller/action method combination is used.</p>

<p>For example, access the following URL </p>

<pre><code>http://sugar-crm.dev/index.php?module=Accounts
</code></pre>

<p>and you land on the default accounts page.  That is, we’ve added a single query string to the URL named <code>module</code>, and set its value to <code>Accounts</code>. In other words, the default page for the <code>Accounts</code> module. </p>

<p>This means if we want to create a module named <code>Helloworld</code>, we access its default landing page at the following URL</p>

<pre><code>http://sugar-crm.dev/index.php?module=Helloworld
</code></pre>

<p>If you load the above URL in your SugarCRM system you’ll get the following error</p>

<blockquote>
  <p>Error: Module Helloworld does not exist.</p>
</blockquote>

<p>That’s because (duh!) we haven’t added any code for our module to the system yet.  </p>

<p>To do so, simply create a folder with your module’s name in the <code>modules</code> folder</p>

<pre><code>$ mkdir modules/Helloworld
</code></pre>

<p>The <code>modules</code> folder is where all SugarCRM modules live.  Create the above folder and reload you page.  You should see something like this</p>

<p><img src="Alan%20Storm%20%20Sugar%20CRM%20Hello%20World%20for%20PHP%20Developers_files/module-empty.png" border="0" height="403" width="733"></p>

<p>So, we have our user interface chrome for the application, but now there’s a misleading error message</p>

<blockquote>
  <p>You do not have access to this area. Contact your site administrator to obtain access.</p>
</blockquote>

<p>Although you wouldn’t think it, this is SugarCRM telling us it can’t find a view to display. </p>

<h2>View First</h2>

<p>SugarCRM is what I like to call a “view first” system.  In most MVC 
systems when you’re creating a new entry point for your application, 
first you create a controller, then you add an action method, and then 
the action method determines which views to render and/or kicks off a 
more complicated rendering process.</p>

<p>With a view first system there’s a default controller being used, and
 all the end-user-programmer needs to do is create a view file.  To 
setup the a view for the default module landing page we created above, 
add the following folder to your system</p>

<pre><code>mkdir modules/Helloworld/views
</code></pre>

<p>and then create the following file with the following content</p>

<div style="width:800px"><div><div id="highlighter_685394" class="syntaxhighlighter  php"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="php plain">#File: modules/Helloworld/views/view.list.php</code></div><div class="line number2 index1 alt1"><code class="php plain">&lt;?php</code></div><div class="line number3 index2 alt2"><code class="php keyword">class</code> <code class="php plain">HelloworldViewList </code><code class="php keyword">extends</code> <code class="php plain">SugarView{</code></div><div class="line number4 index3 alt1"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php keyword">public</code> <code class="php keyword">function</code> <code class="php plain">display()</code></div><div class="line number5 index4 alt2"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php plain">{</code></div><div class="line number6 index5 alt1"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php functions">echo</code> <code class="php string">'&lt;h1&gt;Hello World&lt;/h1&gt;'</code><code class="php plain">;</code></div><div class="line number7 index6 alt2"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php plain">}</code></div><div class="line number8 index7 alt1"><code class="php plain">}&nbsp;&nbsp;&nbsp; </code></div></div></td></tr></tbody></table></div></div></div>

<p>Reload your page, and viola! The error message is gone and there’s your Hello World content</p>

<p><img src="Alan%20Storm%20%20Sugar%20CRM%20Hello%20World%20for%20PHP%20Developers_files/module-view.png" border="0" height="403" width="733"></p>

<p>Before we flip out about HTML in PHP code, let’s breakdown what we 
just did.    By default, every SugarCRM view has a type.  The default 
view type is <code>list</code>.  (This probably doesn’t seem very intuitive, but trust us, we’ll get there)</p>

<p>The view file’s naming convention is</p>

<pre><code>view.[TYPE].php
</code></pre>

<p>which means <code>view.list.php</code> in our case.  The view <strong>class</strong> is named</p>

<pre><code>[Modulename]View[Type]
</code></pre>

<p>with the view type being “first letter uppercase”.  Again, in our case that’s <code>HelloworldViewList</code>.  All view classes ultimately inherit from the <code>SugarView</code> class.</p>

<p>Wait, what?  View <strong>class</strong>?  Where’s the template file!?  In its simplest form, a view in Sugar CRM is a class with a method named <code>display</code>.  The <code>display</code> method is responsible for creating the HTML to be returned to the browser.  It’s also responsible for <code>echo</code>ing or <code>print</code>
 this output —&nbsp;the SugarCRM framework will use output buffering to 
put off output until the appropriate time.  You can see this in action 
by changing your view to the following.</p>

<div style="width:800px"><div><div id="highlighter_543154" class="syntaxhighlighter  php"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div><div class="line number9 index8 alt2">9</div><div class="line number10 index9 alt1">10</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="php plain">#File: modules/Helloworld/views/view.list.php</code></div><div class="line number2 index1 alt1"><code class="php plain">&lt;?php</code></div><div class="line number3 index2 alt2"><code class="php keyword">class</code> <code class="php plain">HelloworldViewList </code><code class="php keyword">extends</code> <code class="php plain">SugarView{</code></div><div class="line number4 index3 alt1"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php keyword">public</code> <code class="php keyword">function</code> <code class="php plain">display()</code></div><div class="line number5 index4 alt2"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php plain">{</code></div><div class="line number6 index5 alt1"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php functions">echo</code> <code class="php string">'&lt;h1&gt;Hello World&lt;/h1&gt;'</code><code class="php plain">;</code></div><div class="line number7 index6 alt2"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php plain">ob_end_clean();</code></div><div class="line number8 index7 alt1"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php functions">exit</code><code class="php plain">(</code><code class="php constants">__METHOD__</code><code class="php plain">);</code></div><div class="line number9 index8 alt2"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php plain">}</code></div><div class="line number10 index9 alt1"><code class="php plain">}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </code></div></div></td></tr></tbody></table></div></div></div>

<p>Here we’ve <code>echo</code>ed our Hello World message, and then immediately called the <code>ob_end_clean</code> function, which stops output buffering and discards the current buffer.   Then, we immediately <code>exit</code>.  If you’re not familiar with output buffering, you might expect the page to still display its chrome.  However, if you refresh</p>

<p><img src="Alan%20Storm%20%20Sugar%20CRM%20Hello%20World%20for%20PHP%20Developers_files/module-exit.png" border="0" height="403" width="733"></p>

<p>you’ll see <strong>only</strong> the output from the <code>exit</code>.  That’s because SugarCRM was holding <strong>all</strong>
 the output in the buffer, and normally wouldn’t release it until later 
in the bootstrap process.  You’ll want to keep this default level of 
buffering in mind if you’re using output buffering yourself, plan to set
 any custom PHP headers, or do anything else where the timing of the 
output is important.     </p>

<p>I know you’re probably cringing at <code>echo</code>ing out raw HTML 
—&nbsp;and we share your distaste. This was only a pedagogical tactic.  
In practice, SugarCRM views will either <code>include</code> other PHP files, or pass off responsibility for output to <strong>another</strong> class.  </p>

<p>For example, if you look at the view class which renders the home page</p>

<div style="width:800px"><div><div id="highlighter_178068" class="syntaxhighlighter  php"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div><div class="line number9 index8 alt2">9</div><div class="line number10 index9 alt1">10</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="php plain">#File: modules/Home/views/view.list.php</code></div><div class="line number2 index1 alt1"><code class="php keyword">class</code> <code class="php plain">HomeViewList </code><code class="php keyword">extends</code> <code class="php plain">ViewList{</code></div><div class="line number3 index2 alt2"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php comments">//...</code></div><div class="line number4 index3 alt1"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php keyword">function</code> <code class="php plain">display(){</code></div><div class="line number5 index4 alt2"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php keyword">global</code> <code class="php variable">$mod_strings</code><code class="php plain">, </code><code class="php variable">$export_module</code><code class="php plain">, </code><code class="php variable">$current_language</code><code class="php plain">, </code><code class="php variable">$theme</code><code class="php plain">, </code><code class="php variable">$current_user</code><code class="php plain">, </code><code class="php variable">$dashletData</code><code class="php plain">, </code><code class="php variable">$sugar_flavor</code><code class="php plain">;</code></div><div class="line number6 index5 alt1"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php variable">$this</code><code class="php plain">-&gt;processMaxPostErrors();</code></div><div class="line number7 index6 alt2"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php keyword">include</code><code class="php plain">(</code><code class="php string">'modules/Home/index.php'</code><code class="php plain">);</code></div><div class="line number8 index7 alt1"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php plain">}</code></div><div class="line number9 index8 alt2"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php comments">//...</code></div><div class="line number10 index9 alt1"><code class="php plain">}&nbsp;&nbsp; </code></div></div></td></tr></tbody></table></div></div></div>

<p>you can see it’s main rendering logic is in the included PHP file <code>modules/Home/index.php</code>.  </p>

<p>If you look at the view class which renders the User’s edit page</p>

<div style="width:800px"><div><div id="highlighter_705784" class="syntaxhighlighter  php"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="php plain">#File: modules/Users/views/view.edit.php</code></div><div class="line number2 index1 alt1"><code class="php keyword">class</code> <code class="php plain">UsersViewEdit </code><code class="php keyword">extends</code> <code class="php plain">ViewEdit {</code></div><div class="line number3 index2 alt2"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php keyword">function</code> <code class="php plain">display(){</code></div><div class="line number4 index3 alt1"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php comments">//...</code></div><div class="line number5 index4 alt2"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php functions">echo</code> <code class="php variable">$this</code><code class="php plain">-&gt;ev-&gt;display(</code><code class="php variable">$this</code><code class="php plain">-&gt;showTitle);</code></div><div class="line number6 index5 alt1"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php plain">}</code></div><div class="line number7 index6 alt2"><code class="php plain">}</code></div></div></td></tr></tbody></table></div></div></div>

<p>you’ll see it ultimately calls the <code>display</code> method of another object stored in the <code>$this-&gt;ev</code> property.  </p>

<p>Also, all view objects have a property named <code>ss</code></p>

<pre><code>$this-&gt;ss;
</code></pre>

<p>This <code>ss</code> property contains a reference to a <code>Sugar_Smarty</code>
 class.  If you’re familiar with the Smarty PHP template system, you can
 use this object to render your page via Smarty templates.     </p>

<p>The point isn’t to bless one method as canonical over the others.  
Rather, as a developer, you need to be aware there’s a wide variety in 
how SugarCRM might render its HTML, but that the view object’s <code>display</code> method is the one common entry point for all view rendering.</p>

<h2>Creating a Controller</h2>

<p>Even though SugarCRM is view first, there’s still a controller behind
 the scenes.  If your module doesn’t have a controller, the system will 
assume you want to use the <code>SugarController</code> class for your controller object</p>

<div style="width:800px"><div><div id="highlighter_724751" class="syntaxhighlighter  php"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="php plain">#File: </code><code class="php keyword">include</code><code class="php plain">/MVC/Controller/SugarController.php</code></div><div class="line number2 index1 alt1"><code class="php plain">&lt;?php</code></div><div class="line number3 index2 alt2"><code class="php keyword">class</code> <code class="php plain">SugarController{&nbsp;&nbsp;&nbsp; </code></div><div class="line number4 index3 alt1"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php comments">//...</code></div><div class="line number5 index4 alt2"><code class="php plain">}</code></div></div></td></tr></tbody></table></div></div></div>

<p>This controller contains a number of  default action methods and setup code, including the setup of the initial view type of <code>list</code>.
  If these defaults aren’t good enough, or you just feel naked without 
your own controller, creating one for your module is relatively simple. 
 Just create a file at the following location with the following content</p>

<div style="width:800px"><div><div id="highlighter_34536" class="syntaxhighlighter  php"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="php plain">#File: modules/Helloworld/controller.php</code></div><div class="line number2 index1 alt1"><code class="php plain">&lt;?php</code></div><div class="line number3 index2 alt2"><code class="php keyword">class</code> <code class="php plain">HelloworldController </code><code class="php keyword">extends</code> <code class="php plain">SugarController</code></div><div class="line number4 index3 alt1"><code class="php plain">{</code></div><div class="line number5 index4 alt2">&nbsp;</div><div class="line number6 index5 alt1"><code class="php plain">}&nbsp;&nbsp;&nbsp; </code></div></div></td></tr></tbody></table></div></div></div>

<p>Each module in SugarCRM has a <strong>single</strong> controller file.  There’s no file naming convention to be aware of — just put it in a file named <code>controller.php</code> at the root of the module.  The controller’s <strong>class</strong> name format is</p>

<pre><code>[Modulename]Controller
</code></pre>

<p>which in our case means <code>HelloworldController</code>, and all controllers extend the base <code>SugarController</code>. </p>

<p>If we reload the page with the above in place, we won’t see any 
change in behavior.  That’s because we’ve defined an empty controller 
with no action methods — our module is effectively using the same base 
controller functionality it was before.  Let’s change that!  </p>

<p>The default action method name for a controller is <code>listview</code>, which means to define the <code>listview</code> action method, we’d change our controller to match the following</p>

<div style="width:800px"><div><div id="highlighter_891967" class="syntaxhighlighter  php"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div><div class="line number9 index8 alt2">9</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="php plain">#File: modules/Helloworld/controller.php</code></div><div class="line number2 index1 alt1"><code class="php plain">&lt;?php</code></div><div class="line number3 index2 alt2"><code class="php keyword">class</code> <code class="php plain">HelloworldController </code><code class="php keyword">extends</code> <code class="php plain">SugarController</code></div><div class="line number4 index3 alt1"><code class="php plain">{</code></div><div class="line number5 index4 alt2"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php keyword">public</code> <code class="php keyword">function</code> <code class="php plain">action_listview()</code></div><div class="line number6 index5 alt1"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php plain">{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </code></div><div class="line number7 index6 alt2"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php plain">var_dump(</code><code class="php constants">__METHOD__</code><code class="php plain">);</code></div><div class="line number8 index7 alt1"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php plain">}&nbsp;&nbsp;&nbsp; </code></div><div class="line number9 index8 alt2"><code class="php plain">}&nbsp;&nbsp;&nbsp; </code></div></div></td></tr></tbody></table></div></div></div>

<p>An action method is a public method with the name format</p>

<pre><code>action_[action name]
</code></pre>

<p>In our case, that’s <code>action_listview</code>.  As you can see, we’ve added a single <code>var_dump</code> to the method.  If you reload the page, you’ll see that this <code>var_dump</code> is called <strong>before</strong> any other output is sent to the browser, which outputs the magic <code>__METHOD__</code>  constant at the top of the page</p>

<p><img src="Alan%20Storm%20%20Sugar%20CRM%20Hello%20World%20for%20PHP%20Developers_files/module-controller-noview.png" border="0" height="403" width="733"></p>

<h2>Setting the View Type</h2>

<p>Let’s take a look at that screen shot again</p>

<p><img src="Alan%20Storm%20%20Sugar%20CRM%20Hello%20World%20for%20PHP%20Developers_files/module-controller-noview.png" border="0" height="403" width="733"></p>

<p>Sharp eyes may have noticed something.  Specifically, by adding a controller method, we seem to have lost our view!</p>

<p>That’s because the default <code>SugarController</code> was setting this for us in the <strong>default</strong> <code>action_listview</code> method.</p>

<div style="width:800px"><div><div id="highlighter_211937" class="syntaxhighlighter  php"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="php plain">#File: </code><code class="php keyword">include</code><code class="php plain">/MVC/Controller/SugarController.php</code></div><div class="line number2 index1 alt1"><code class="php comments">//...</code></div><div class="line number3 index2 alt2"><code class="php keyword">protected</code> <code class="php keyword">function</code> <code class="php plain">action_listview(){</code></div><div class="line number4 index3 alt1"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php comments">//...</code></div><div class="line number5 index4 alt2"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php variable">$this</code><code class="php plain">-&gt;view = </code><code class="php string">'list'</code><code class="php plain">;</code></div><div class="line number6 index5 alt1"><code class="php plain">}</code></div><div class="line number7 index6 alt2"><code class="php comments">//...</code></div></div></td></tr></tbody></table></div></div></div>

<p>Specifically, the line <code>$this-&gt;view = 'list';</code> is what set the view type to list.</p>

<p>We can fix this one of two ways.  The first is to be a responsible object oriented programmer and call/return our parent method </p>

<div style="width:800px"><div><div id="highlighter_353250" class="syntaxhighlighter  php"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div><div class="line number9 index8 alt2">9</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="php plain">#File: modules/Helloworld/controller.php</code></div><div class="line number2 index1 alt1"><code class="php plain">&lt;?php</code></div><div class="line number3 index2 alt2"><code class="php keyword">class</code> <code class="php plain">HelloworldController </code><code class="php keyword">extends</code> <code class="php plain">SugarController</code></div><div class="line number4 index3 alt1"><code class="php plain">{</code></div><div class="line number5 index4 alt2"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php keyword">public</code> <code class="php keyword">function</code> <code class="php plain">action_listview()</code></div><div class="line number6 index5 alt1"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php plain">{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </code></div><div class="line number7 index6 alt2"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php keyword">return</code> <code class="php plain">parent::action_listview();</code></div><div class="line number8 index7 alt1"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php plain">}&nbsp;&nbsp;&nbsp; </code></div><div class="line number9 index8 alt2"><code class="php plain">} </code></div></div></td></tr></tbody></table></div></div></div>

<p>Reload with the above in place, any our view will be back.  </p>

<p>The second, and more interesting, fix  would be to set the view type ourselves.</p>

<div style="width:800px"><div><div id="highlighter_613387" class="syntaxhighlighter  php"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div><div class="line number9 index8 alt2">9</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="php plain">#File: modules/Helloworld/controller.php</code></div><div class="line number2 index1 alt1"><code class="php plain">&lt;?php</code></div><div class="line number3 index2 alt2"><code class="php keyword">class</code> <code class="php plain">HelloworldController </code><code class="php keyword">extends</code> <code class="php plain">SugarController</code></div><div class="line number4 index3 alt1"><code class="php plain">{</code></div><div class="line number5 index4 alt2"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php keyword">public</code> <code class="php keyword">function</code> <code class="php plain">action_listview()</code></div><div class="line number6 index5 alt1"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php plain">{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </code></div><div class="line number7 index6 alt2"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php variable">$this</code><code class="php plain">-&gt;view = </code><code class="php string">'list'</code><code class="php plain">;</code></div><div class="line number8 index7 alt1"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php plain">}&nbsp;&nbsp;&nbsp; </code></div><div class="line number9 index8 alt2"><code class="php plain">} </code></div></div></td></tr></tbody></table></div></div></div>

<p>Now we’re starting to see a familiar MVC pattern emerge.  The reason 
this is more interesting than just calling the parent method is we’re no
 longer limited to creating a view with the default name of <code>list</code>.  We could now name our view anything we wanted</p>

<div style="width:800px"><div><div id="highlighter_689090" class="syntaxhighlighter  php"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="php variable">$this</code><code class="php plain">-&gt;view = </code><code class="php string">'hello'</code><code class="php plain">;</code></div><div class="line number2 index1 alt1"><code class="php variable">$this</code><code class="php plain">-&gt;view = </code><code class="php string">'foobazbar'</code><code class="php plain">;</code></div></div></td></tr></tbody></table></div></div></div>

<p>or use conditional logic to set different views based on the system 
state.  So long as our view files and classes are named named correctly</p>

<div style="width:800px"><div><div id="highlighter_386436" class="syntaxhighlighter  php"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="php plain">#File: modules/Helloworld/views/view.hello.php</code></div><div class="line number2 index1 alt1"><code class="php plain">&lt;?php</code></div><div class="line number3 index2 alt2"><code class="php keyword">class</code> <code class="php plain">HelloworldViewHello </code><code class="php keyword">extends</code> <code class="php plain">SugarView{</code></div><div class="line number4 index3 alt1"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php keyword">public</code> <code class="php keyword">function</code> <code class="php plain">display()</code></div><div class="line number5 index4 alt2"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php plain">{</code></div><div class="line number6 index5 alt1"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php functions">echo</code> <code class="php string">'&lt;h1&gt;Some other View&lt;/h1&gt;'</code><code class="php plain">;</code></div><div class="line number7 index6 alt2"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php plain">}</code></div><div class="line number8 index7 alt1"><code class="php plain">}</code></div></div></td></tr></tbody></table></div></div></div>

<p>we can name our views anything we like.</p>

<h2>Setting View Variables</h2>

<p>We now know how to create a view in SugarCRM.  We also know how to create a controller.  Next up is all important question</p>

<blockquote>
  <p>How does the controller tell the view about things</p>
</blockquote>

<p>Both SugarCRM view and controller objects have a special array property named <code>$this-&gt;view_object_map</code>.  This array is where you’ll set variables in your controller action for your view.  For example, if you change your <code>listview</code> method to match the following </p>

<div style="width:800px"><div><div id="highlighter_432052" class="syntaxhighlighter  php"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="php plain">#File: modules/Helloworld/controller.php</code></div><div class="line number2 index1 alt1"><code class="php keyword">public</code> <code class="php keyword">function</code> <code class="php plain">action_listview()</code></div><div class="line number3 index2 alt2"><code class="php plain">{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </code></div><div class="line number4 index3 alt1"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php variable">$this</code><code class="php plain">-&gt;view = </code><code class="php string">'list'</code><code class="php plain">;</code></div><div class="line number5 index4 alt2"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php variable">$this</code><code class="php plain">-&gt;view_object_map[</code><code class="php string">'message'</code><code class="php plain">] = </code><code class="php string">'Hello World at '</code> <code class="php plain">. </code><code class="php functions">date</code><code class="php plain">(</code><code class="php string">'Y-m-d H:i:s'</code><code class="php plain">,time());</code></div><div class="line number6 index5 alt1"><code class="php plain">}&nbsp;&nbsp;&nbsp; </code></div></div></td></tr></tbody></table></div></div></div>

<p>and then change your view to reference the same key in the <code>view_object_map</code></p>

<div style="width:800px"><div><div id="highlighter_862760" class="syntaxhighlighter  php"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="php plain">#File: modules/Helloworld/views/view.list.php</code></div><div class="line number2 index1 alt1"><code class="php plain">&lt;?php</code></div><div class="line number3 index2 alt2"><code class="php keyword">class</code> <code class="php plain">HelloworldViewList </code><code class="php keyword">extends</code> <code class="php plain">SugarView{</code></div><div class="line number4 index3 alt1"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php keyword">public</code> <code class="php keyword">function</code> <code class="php plain">display()</code></div><div class="line number5 index4 alt2"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php plain">{</code></div><div class="line number6 index5 alt1"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php functions">echo</code> <code class="php string">'&lt;h1&gt;'</code><code class="php plain">.</code><code class="php variable">$this</code><code class="php plain">-&gt;view_object_map[</code><code class="php string">'message'</code><code class="php plain">].</code><code class="php string">'&lt;/h1&gt;'</code><code class="php plain">;</code></div><div class="line number7 index6 alt2"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php plain">}</code></div><div class="line number8 index7 alt1"><code class="php plain">}</code></div></div></td></tr></tbody></table></div></div></div>

<p>and then reload your page, you’ll see a Hello World message with the date and time included.    </p>

<p><img src="Alan%20Storm%20%20Sugar%20CRM%20Hello%20World%20for%20PHP%20Developers_files/module-withdate.png" border="0" height="403" width="733"></p>

<p>By setting the <code>messages</code> key in the controller, it’s been made available to the view.</p>

<h2>Multiple Action Methods</h2>

<p>While each module in SugarCRM has one, and only one, controller, each
 controller may have multiple action methods.  Let’s say we wanted to 
create an action method named <code>goodbye</code>. First, we’d add the following method to our controller</p>

<div style="width:800px"><div><div id="highlighter_462709" class="syntaxhighlighter  php"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div><div class="line number9 index8 alt2">9</div><div class="line number10 index9 alt1">10</div><div class="line number11 index10 alt2">11</div><div class="line number12 index11 alt1">12</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="php plain">#File: modules/Helloworld/controller.php</code></div><div class="line number2 index1 alt1"><code class="php plain">&lt;?php</code></div><div class="line number3 index2 alt2"><code class="php keyword">class</code> <code class="php plain">HelloworldController </code><code class="php keyword">extends</code> <code class="php plain">SugarController</code></div><div class="line number4 index3 alt1"><code class="php plain">{</code></div><div class="line number5 index4 alt2"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php comments">//...</code></div><div class="line number6 index5 alt1"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php keyword">public</code> <code class="php keyword">function</code> <code class="php plain">action_goodbye()</code></div><div class="line number7 index6 alt2"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php plain">{</code></div><div class="line number8 index7 alt1"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php variable">$this</code><code class="php plain">-&gt;view = </code><code class="php string">'list'</code><code class="php plain">;</code></div><div class="line number9 index8 alt2"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php variable">$this</code><code class="php plain">-&gt;view_object_map[</code><code class="php string">'message'</code><code class="php plain">] = </code><code class="php string">'Goodbye World!'</code><code class="php plain">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </code></div><div class="line number10 index9 alt1"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php plain">}&nbsp;&nbsp;&nbsp; </code></div><div class="line number11 index10 alt2"><code class="php spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="php comments">//...&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </code></div><div class="line number12 index11 alt1"><code class="php plain">}&nbsp;&nbsp; </code></div></div></td></tr></tbody></table></div></div></div>

<p>Notice we’re reusing the <code>list</code> view, but we’re setting a different message. </p>

<p>Next, to access the entry point, we’d add an <code>action</code> query string to our URL</p>

<pre><code>http://sugar-crm.dev/index.php?module=Helloworld&amp;action=goodbye
</code></pre>

<p>Remember, there’s no “smart url” routing in SugarCRM, it’s parameters all the way down.   </p>

<p>Reload the page, and there’s our new message</p>

<p><img src="Alan%20Storm%20%20Sugar%20CRM%20Hello%20World%20for%20PHP%20Developers_files/module-goodbye.png" border="0" height="403" width="733"></p>

<p>Earlier we said <code>listview</code> was the default controller 
action.  Let’s test that out by being explicit with the URL.  Access 
your SugarCRM installation with the following URL</p>

<pre><code>http://sugar-crm.dev/index.php?module=Helloworld&amp;action=listview
</code></pre>

<p>As you can see, this page has the same content as an <code>action</code>-less URL    </p>

<pre><code>http://sugar-crm.dev/index.php?module=Helloworld
</code></pre>

<p>It’s not exactly the sexiest of routing systems, but using the <code>action</code> paramaters means you can create an unlimited number of unique pages in your SugarCRM module/system.</p>

<p><strong>Advanced Tip</strong>: Want to really confuse yourself?  Try accessing your module with an <code>action</code> named <code>index</code></p>

<pre><code>http://sugar-crm.dev/index.php?module=Helloworld&amp;action=index
</code></pre>

<p>You’ll see — the <code>listview</code> page?  </p>

<p><img src="Alan%20Storm%20%20Sugar%20CRM%20Hello%20World%20for%20PHP%20Developers_files/module-index.png" border="0" height="403" width="733"></p>

<p>That’s because we told you a little fib — the <strong>actual</strong> default action for a controller is <code>index</code>. However, SugarCRM’s bootstrap process includes an action aliasing system that automatically turns the <code>index</code> action into <code>listview</code>.  </p>

<p>This isn’t something you need to worry about right now, but it’s 
worth knowing if you’re going to venture into the depths of SugarCRM’s 
application dispatch process, and is an example of how the core system 
code has been shaped by the needs of the specific application. The <code>listview</code> action is the default because most module’s default landing page is a <code>list</code> of all of the module’s objects. </p>

<h2>Wrap Up</h2>

<p>We now know how to </p>

<ul>
<li><p>Create a core SugarCRM module</p></li>
<li><p>Create views for our module</p></li>
<li><p>Create a custom controller and action methods for our module</p></li>
</ul>

<p>That’s the <code>V</code> and the <code>C</code> of MVC out of the way.  Next time we’ll cover SugarCRM’s data <code>M</code>odel,
 or as they’re known is SugarCRM speak — “beans”.  Until then, happy 
coding, and corrections are more than welcome in the comments. </p>

<div class="date">Originally published March  5, 2013</div><div id="disqus_thread"><iframe verticalscrolling="no" horizontalscrolling="no" src="Alan%20Storm%20%20Sugar%20CRM%20Hello%20World%20for%20PHP%20Developers_files/a.html" style="width: 100% ! important; border: medium none ! important; overflow: hidden ! important; height: 603px ! important;" title="Disqus" tabindex="0" scrolling="no" allowtransparency="true" data-disqus-uid="2" id="dsq-2" frameborder="0" width="100%"></iframe></div>
<script type="text/javascript">
	var as_disqus_data = {"uri":"\/sugar_crm_hello_world","identifier":"sugarcrmhelloworld"};
	var disqus_shortname = 'alanstormdotcom'; // required: replace example with your forum shortname

	//The following are highly recommended additional parameters. Remove the slashes in front to use.
	//var disqus_identifier = 'unique_dynamic_id_1234';
	var disqus_identifier = as_disqus_data.identifier;		//'domdocument_php_stop_test';
	var disqus_url = 'http://alanstorm.com' + as_disqus_data.uri; 	//'http://alanstorm.com/domdocument_php_stop';
	jQuery(document).ready(function(){	
		/* * * DON'T EDIT BELOW THIS LINE * * */
		(function() {
			var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
			dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
			(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
		})();
	});
</script>
<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>



		<!-- <em>This article is part of a <a href="/category/sugarcrm#sugarcrm_for_php_developers">longer series</a> 
exploring SugarCRM's features from a PHP developer's point of view. While this article contains useful stand-alone information, you'll want to read the <a href="/category/sugarcrm#sugarcrm_for_php_developers">entire series</a> to fully understand what's going on</em>.
</em>
 -->
	</div>	
</div>

<br style="clear:left">

<div id="copyright">
	Copyright © Alan Storm 1975 – 2014 &nbsp;&nbsp; All Rights Reserved
</div>
	
</div>
<script type="text/javascript">
	$(document).ready(function () {
		$('.diagram-modal').simpleDialog();
		if(-1 == navigator.appVersion.indexOf('Mac') && -1 == navigator.appVersion.indexOf('Mac')) {
			$('ul#nav a').css('font-size','12px');
		}
		
		//prettyPrint();
	});
</script>

<script src="Alan%20Storm%20%20Sugar%20CRM%20Hello%20World%20for%20PHP%20Developers_files/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "UA-322263-2";
urchinTracker();
</script>

</body></html>